#!/usr/bin/python
#-*- coding: utf-8 -*-
from bottle import route, run, request, static_file, template
import sqlite3

import plugins

def get_content_plugin(content_type):
    if content_type in dir(plugins):
        return plugins.__dict__[content_type]
    else:
        try:
            __import__("plugins." + content_type)
            return plugins.__dict__[content_type]
        except:
            print "Error: No plugin available for:", content_type

# --- Static files ----------------------------------------
@route('/static/<filename:path>')
def server_static(filename="index.html"):
    return static_file(filename, root='./static')

# --- Editors ----------------------------------------
@route('/editor/<type>/<uid:int>')
def editor():
    pass

# --- Main Page ----------------------------------------
@route('/')
def main():
    conn = sqlite3.connect("k.db")
    c = conn.cursor()
    c.execute("""SELECT tags.uid, tags.name, COUNT(links.content_uid) FROM tags
    LEFT JOIN links ON tags.uid=links.tag_uid
    GROUP BY tags.uid
    """)
    # Tags page content
    listOfTags = c.fetchall()
    c.close()
    conn.commit()
    conn.close()
    return template("main", tags=listOfTags)

# --- Content ----------------------------------------
@route('/contents/<content_type>/<content_uid:int>')
def content_details(content_type, content_uid):
    # Open DB
    conn = sqlite3.connect("k.db")
    c = conn.cursor()

    result = template('contents/details_header', content_type=content_type, content_uid=content_uid)
    plugin = get_content_plugin(content_type)
    if plugin:
        result += plugin.render_details(c, content_uid)
    else:
        result += "Plugin not available for content type: %s" % content_type
    result += template('contents/details_footer')
    return result

@route('/contents/<content_type>/<content_uid:int>/edit')
def content_edit(content_type, content_uid):
    # Open DB
    conn = sqlite3.connect("k.db")
    c = conn.cursor()

    result = template('contents/editor_header', content_type=content_type, content_uid=content_uid)
    plugin = get_content_plugin(content_type)
    if plugin:
        result += plugin.render_editor(c, content_uid)
    else:
        result += "Plugin not available for content type: %s" % content_type
    result += template('contents/editor_footer')
    return result

@route('/contents/<content_type>/<content_uid:int>/update', method="POST")
def content_update(content_type, content_uid):
    print "Update: %s.%s" % (content_type, content_uid)
    # Open DB
    conn = sqlite3.connect("k.db")
    c = conn.cursor()

    plugin = get_content_plugin(content_type)
    if plugin:
        try:
            # Process update in plugin
            short_html = plugin.commit_update(c, request, content_uid)
            if not short_html:
                short_html = "No preview"
            # Update short html
            c.execute("""UPDATE contents SET html="%s" WHERE uid=%s""" % (short_html, content_uid))
            c.close()
            conn.commit()
            conn.close()
            # Return dialog display, linking to home
            return template('contents/update_success', content_type=content_type, content_uid=content_uid, html=short_html)
        except:
            pass
    return template('contents/update_failed', content_type=content_type, content_uid=content_uid)
    
# --- Tags ----------------------------------------
@route('/tags/new', method='POST')
def tags_new():
    name = request.forms['name']
    if name:
        # Open DB
        conn = sqlite3.connect("k.db")
        c = conn.cursor()
        # Insert tag
        c.execute("INSERT INTO tags VALUES(NULL, '%s')" % name)
        tag_uid = c.lastrowid
        c.execute("INSERT INTO links VALUES(%s, 0)" % tag_uid)
        c.close()
        # Save
        conn.commit()
        conn.close()
        # Return html code to insert in tags list
        return template("tags_list", tags=[(tag_uid, name, 0)])

@route('/tags/<tag_uid:int>')
def tags_details(tag_uid):
    # Open DB
    conn = sqlite3.connect("k.db")
    c = conn.cursor()
    c.execute("""SELECT tags.uid, tags.name FROM tags WHERE uid=%s""" % (tag_uid))
    (_, tag_name) = c.fetchone()

    # Query for tags contents
    c.execute("""SELECT GROUP_CONCAT(DISTINCT tags.name), contents.ext_type, links.content_uid, contents.html FROM links 
    LEFT JOIN links AS links2 ON links.content_uid=links2.content_uid
    LEFT JOIN tags ON tags.uid=links2.tag_uid
    INNER JOIN contents ON links.content_uid=contents.uid
    WHERE links.tag_uid=%s 
    GROUP BY links2.content_uid
    """ % (tag_uid))

    # Render HTML
    return template("tags_details", tag_uid=tag_uid, tag_name=tag_name, links=c.fetchall())

#@route('/tags/delete/<uid:int>')
#def tags_delete(uid):
#    # Open DB
#    conn = sqlite3.connect("k.db")
#    c = conn.cursor()
#    # Insert tag
#    c.execute("DELETE FROM tags WHERE uid=%s" % uid)
#    tagsCount = c.rowcount
#    c.execute("DELETE FROM links WHERE tag_uid=%s" % uid)
#    linksCount = c.rowcount
#    c.close()
#    # Save
#    conn.commit()
#    conn.close()
#    # Return html code to insert in tags list
#    return template("tags_delete", tagsCount=tagsCount, linksCount=linksCount)

# --- Install -----
@route('/install')
def install():
    conn = sqlite3.connect("k.db")
    c = conn.cursor()
    c.execute("CREATE TABLE tags (uid INTEGER PRIMARY KEY, name)")
    c.execute("CREATE TABLE contents (uid INTEGER PRIMARY KEY, html, ext_type)")
    c.execute("CREATE TABLE links (tag_uid, content_uid)")
    c.execute("CREATE TABLE texts (content_uid, value)")
    c.execute("INSERT INTO tags VALUES(NULL, 'Sample')")
    tag_uid = c.lastrowid
    c.execute("INSERT INTO tags VALUES(NULL, 'Sample 2')")
    tag_uid2 = c.lastrowid
    c.execute("INSERT INTO contents VALUES(NULL, 'A sample ...', 'texts')")
    content_uid = c.lastrowid
    c.execute("INSERT INTO texts VALUES(%s, 'A sample text')" % content_uid)
    c.execute("INSERT INTO links VALUES (%s, %s)" % (tag_uid, content_uid))
    c.execute("INSERT INTO links VALUES (%s, %s)" % (tag_uid2, content_uid))
    c.close()
    conn.commit()
    conn.close()
    return "k.db created"

run(port=8080, debug=True, reloader=True)
